package cn.ecpay.unionpay.settle.controller;

import cn.ecpay.unionpay.settle.Common.CommonUtil;
import cn.ecpay.unionpay.settle.Common.DateUtil;
import cn.ecpay.unionpay.settle.Common.RespCode;
import cn.ecpay.unionpay.settle.Common.UnionpayDict;
import cn.ecpay.unionpay.settle.dao.ReturnMoneyDao;
import cn.ecpay.unionpay.settle.entity.db.TPvReturnMoney;
import cn.ecpay.unionpay.settle.util.CommonBase;
import cn.ecpay.unionpay.settle.util.FsasService;
import cn.ecpay.unionpay.settle.util.LogUtil;
import cn.ecpay.unionpay.settle.util.SDKConfig;
import org.rex.db.exception.DBException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 回款接口
 *  Created by zhaoyanzeng on 2018/11/6.
 */
@RestController
public class ReturnMoneyController {

    @Resource
    private ReturnMoneyDao returnMoneyDao;

    @RequestMapping(value = "/returnMoney",method = RequestMethod.POST)
    public String returnMoney(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        Map<String, String> contentData = convertContentMap(req);
        if(isExistTxn(contentData.get("txnNo"),contentData.get("txnDate"))){
            return "重复交易";
        }
        TPvReturnMoney returnMoney = new TPvReturnMoney();
        Map<String, String> reqData = FsasService.sign(contentData, CommonBase.encoding);
        reqDataConvertReturnMoney(returnMoney,reqData);
        String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl();
        Map<String, String> rspData = FsasService.doPost(reqData, requestBackUrl, CommonBase.encoding);
        rspDataConvertReturnMoney(returnMoney,rspData);
        if (!rspData.isEmpty()) {
            if (FsasService.validate(rspData, CommonBase.encoding)) {
                LogUtil.writeLog("验证签名成功");
                returnMoney.setRespValidate("1");//验签成功
                String respCode = rspData.get("respCode");
                if (("00").equals(respCode)) {
                    //TODO 交易成功
                } else {
                    //TODO
                }
            } else {
                LogUtil.writeErrorLog("验证签名失败");
                returnMoney.setRespValidate("0");//验签失败
                //TODO 检查验证签名失败的原因
            }
        } else {
            //未返回正确的http状态
            LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
        }

        try {
            returnMoneyDao.insert(returnMoney);
        } catch (DBException e) {
            e.printStackTrace();
        }
        String reqMessage = CommonBase.genHtmlResult(reqData);
        String rspMessage = CommonBase.genHtmlResult(rspData);
        //TODO 暂时返回map，后期约定返回接口数据
        return "回款交易请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage ;
    }

    /**
     * 回款异步通知
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @RequestMapping(value = "/returnMoneyNotify", method = RequestMethod.POST)
    public void returnMoneyNotify(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        LogUtil.writeLog("回款异步通知开始");

        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = CommonUtil.getAllRequestParamStream(req);
        LogUtil.printRequestLog(reqParam);

        if (!FsasService.validate(reqParam, CommonBase.encoding)) {
            LogUtil.writeLog("验证签名结果[失败].");

        } else {
            LogUtil.writeLog("验证签名结果[成功].");
            String respCode = reqParam.get("respCode");
            if (RespCode.RESP_SUCCESS.equals(respCode)) {
                //TODO 成功
            } else {
                //TODO 失败
            }
            LogUtil.writeLog("respCode=" + respCode);

        }
        LogUtil.writeLog("回款异步通知结束");
    }


    /**
     * 请求数据
     *
     * @param req
     * @return
     */
    private Map<String, String> convertContentMap(HttpServletRequest req) {
        String acqInsCode = req.getParameter("acqInsCode");
        String txnNo = req.getParameter("txnNo");
        String txnDate = req.getParameter("txnDate");
        String insSeq = req.getParameter("insSeq");
        String payerAcctNo = req.getParameter("payerAcctNo");
        String payerAcctName = req.getParameter("payerAcctName");
        String txnAmt = req.getParameter("txnAmt");

        Map<String, String> contentData = new HashMap<String, String>();
        /***银联资金结算接入系统，产品参数，除了encoding自行选择外其他不需修改***/
        contentData.put("version", CommonBase.version);                  //版本号
        contentData.put("encoding", CommonBase.encoding);             //字符集编码 可以使用UTF-8,GBK两种方式
        contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法
        contentData.put("txnType", UnionpayDict.TXN_TYPE_RETURNMONEY);                                   //交易类型 04-回款
        contentData.put("txnNo", txnNo);                                    //交易流水号
        contentData.put("acqInsCode", acqInsCode);                        //机构代码
        contentData.put("txnDate", txnDate);                               //交易日期
        contentData.put("sndTime", CommonBase.getSendTime());      //发送时间 格式HHmmss
        contentData.put("insSeq", insSeq);                                  //头寸序号   以机构代码 +头寸序号在银联系统内对应的银行账户为准
        contentData.put("payerAcctNo", payerAcctNo);                //收款方账号
        contentData.put("payerAcctName", payerAcctName);        //收款方账户名称
        contentData.put("currencyCode", "156");                          //币种
        contentData.put("txnAmt", txnAmt);                                 //金额
//        contentData.put("backUrl", CommonBase.backUrl);
        return contentData;
    }

    //申请参数
    private void reqDataConvertReturnMoney(TPvReturnMoney returnMoney,Map<String, String> reqData) {
        returnMoney.setTxnNo(reqData.get("txnNo"));
        returnMoney.setAcqInsCode(reqData.get("acqInsCode"));
        returnMoney.setTxnType(reqData.get("txnType"));
        returnMoney.setTxnDate(reqData.get("txnDate"));
        returnMoney.setSendTime(reqData.get("sndTime"));
        returnMoney.setInsSeq(reqData.get("insSeq"));
        returnMoney.setPayerAcctNo(reqData.get("payerAcctNo"));
        returnMoney.setPayerAcctName(reqData.get("payerAcctName"));
        returnMoney.setCurrencyCode(reqData.get("currencyCode"));
        returnMoney.setTxnAmt(reqData.get("txnAmt"));
        returnMoney.setCreateTime(DateUtil.getDateTo19(new Date()));
    }

    //同步返回结果
    private void rspDataConvertReturnMoney(TPvReturnMoney returnMoney,Map<String, String> rspData) {
        returnMoney.setRespCode(rspData.get("respCode"));
        returnMoney.setRespMsg(rspData.get("respMsg"));
    }

    /**
     * 交易是否已存在
     *
     * @return
     */
    public boolean isExistTxn(String txnNo, String txnDate) {
        try {
            return returnMoneyDao.isExistTxn(txnNo, txnDate);
        } catch (DBException e) {
            e.printStackTrace();
            return false;
        }
    }
}
